#!/usr/bin/env node

/**
 * Build script for Tauri Modern Template
 * Handles production builds with optimization and bundling
 */

import { spawn, exec } from 'child_process';
import fs from 'fs';
import path from 'path';
import os from 'os';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Colors for console output
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
};

function log(message, color = colors.reset) {
  console.log(`${color}${message}${colors.reset}`);
}

function logInfo(message) {
  log(`ℹ ${message}`, colors.blue);
}

function logSuccess(message) {
  log(`✓ ${message}`, colors.green);
}

function logWarning(message) {
  log(`⚠ ${message}`, colors.yellow);
}

function logError(message) {
  log(`✗ ${message}`, colors.red);
}

// Clean previous build artifacts
function cleanBuildArtifacts() {
  logInfo('Cleaning previous build artifacts...');
  
  const dirsToClean = [
    'dist',
    'src-tauri/target/release',
    'src-tauri/target/debug',
  ];

  for (const dir of dirsToClean) {
    if (fs.existsSync(dir)) {
      fs.rmSync(dir, { recursive: true, force: true });
      logSuccess(`Cleaned ${dir}`);
    }
  }
}

// Run type checking
function runTypeCheck() {
  logInfo('Running TypeScript type checking...');
  
  try {
    execSync('npm run type-check', { stdio: 'inherit' });
    logSuccess('Type checking passed');
  } catch (error) {
    logError('Type checking failed');
    process.exit(1);
  }
}

// Run linting
function runLinting() {
  logInfo('Running ESLint...');
  
  try {
    execSync('npm run lint', { stdio: 'inherit' });
    logSuccess('Linting passed');
  } catch (error) {
    logWarning('Linting issues found, but continuing build...');
  }
}

// Run tests
function runTests() {
  logInfo('Running tests...');
  
  try {
    // Add test command when tests are implemented
    // require('child_process').execSync('npm test', { stdio: 'inherit' });
    logInfo('No tests configured yet');
  } catch (error) {
    logError('Tests failed');
    process.exit(1);
  }
}

// Build the application
function buildApplication(options = {}) {
  logInfo('Building application...');
  
  const args = ['tauri', 'build'];
  
  if (options.debug) {
    args.push('--debug');
  }
  
  if (options.verbose) {
    args.push('--verbose');
  }

  if (options.target) {
    args.push('--target', options.target);
  }

  const buildProcess = spawn('npm', args, {
    stdio: 'inherit',
    shell: true,
  });

  return new Promise((resolve, reject) => {
    buildProcess.on('close', (code) => {
      if (code === 0) {
        logSuccess('Build completed successfully');
        resolve();
      } else {
        logError(`Build failed with code ${code}`);
        reject(new Error(`Build failed with code ${code}`));
      }
    });
  });
}

// Generate build info
function generateBuildInfo() {
  logInfo('Generating build information...');
  
  const packageJsonPath = path.join(__dirname, '..', 'package.json');
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));

  const buildInfo = {
    version: packageJson.version,
    buildTime: new Date().toISOString(),
    platform: os.platform(),
    arch: os.arch(),
    nodeVersion: process.version,
    commit: getBuildCommit(),
  };

  const buildInfoPath = path.join('dist', 'build-info.json');
  
  // Ensure dist directory exists
  if (!fs.existsSync('dist')) {
    fs.mkdirSync('dist', { recursive: true });
  }
  
  fs.writeFileSync(buildInfoPath, JSON.stringify(buildInfo, null, 2));
  logSuccess('Build information generated');
}

// Get current git commit
function getBuildCommit() {
  try {
    return execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
  } catch (error) {
    return 'unknown';
  }
}

// Copy additional files
function copyAdditionalFiles() {
  logInfo('Copying additional files...');
  
  const filesToCopy = [
    { src: 'README.md', dest: 'dist/README.md' },
    { src: 'LICENSE', dest: 'dist/LICENSE' },
  ];

  for (const file of filesToCopy) {
    if (fs.existsSync(file.src)) {
      fs.copyFileSync(file.src, file.dest);
      logSuccess(`Copied ${file.src} to ${file.dest}`);
    }
  }
}

// Show build summary
function showBuildSummary() {
  logInfo('Build Summary:');
  
  const bundleDir = 'src-tauri/target/release/bundle';
  if (fs.existsSync(bundleDir)) {
    const files = fs.readdirSync(bundleDir, { recursive: true });
    
    for (const file of files) {
      const filePath = path.join(bundleDir, file);
      if (fs.statSync(filePath).isFile()) {
        const stats = fs.statSync(filePath);
        const size = (stats.size / 1024 / 1024).toFixed(2);
        log(`  ${file} (${size} MB)`, colors.cyan);
      }
    }
  }
}

// Show help information
function showHelp() {
  console.log(`
${colors.bright}Tauri Modern Template Build Script${colors.reset}

${colors.cyan}Usage:${colors.reset}
  npm run build [options]

${colors.cyan}Options:${colors.reset}
  --debug         Build in debug mode
  --verbose       Enable verbose output
  --skip-checks   Skip type checking and linting
  --target        Specify build target
  --help          Show this help message

${colors.cyan}Examples:${colors.reset}
  npm run build
  npm run build -- --debug
  npm run build -- --target x86_64-pc-windows-msvc
  npm run build -- --skip-checks --verbose
`);
}

// Main function
async function main() {
  const args = process.argv.slice(2);

  if (args.includes('--help')) {
    showHelp();
    return;
  }

  const options = {
    debug: args.includes('--debug'),
    verbose: args.includes('--verbose'),
    skipChecks: args.includes('--skip-checks'),
    target: args.includes('--target') ? args[args.indexOf('--target') + 1] : null,
  };

  try {
    cleanBuildArtifacts();
    
    if (!options.skipChecks) {
      runTypeCheck();
      runLinting();
      runTests();
    }
    
    await buildApplication(options);
    generateBuildInfo();
    copyAdditionalFiles();
    showBuildSummary();
    
    logSuccess('Build process completed successfully!');
  } catch (error) {
    logError(`Build process failed: ${error.message}`);
    process.exit(1);
  }
}

// Run the script
main();

export {
  cleanBuildArtifacts,
  runTypeCheck,
  runLinting,
  runTests,
  buildApplication,
  generateBuildInfo,
};
